package com.example.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.dojo.JsonData;
import com.example.dojo.SensitiveWordFindReqBody;
import com.example.dojo.SensitiveWordDto;
import com.example.entity.SensitiveWord;
import com.example.enums.StatusEnum;
import com.example.service.SensitiveWordBsService;
import com.example.service.SensitiveWordService;

@RestController
@RequestMapping("/sensitiveWord")
public class SensitiveWordController {

    @Autowired
    private SensitiveWordService sensitiveWordService;

    @Autowired
    private SensitiveWordBsService sensitiveWordBsService;

    @GetMapping("")
    public List<SensitiveWordDto> getSensitiveWord() {
        List<SensitiveWordDto> words = sensitiveWordService.list().stream().map(sw -> {
            SensitiveWordDto swdto = new SensitiveWordDto();
            swdto.setId(sw.getId());
            swdto.setWord(sw.getWord());
            swdto.setStatus(sw.getStatus().getCode());
            swdto.setCreateTime(sw.getCreateTime());
            return swdto;
        }).collect(Collectors.toList());
        return words;
    }

    @GetMapping("/deny")
    public List<SensitiveWordDto> getDeny() {
        List<SensitiveWordDto> words = sensitiveWordService.listDeny().stream().map(sw -> {
            SensitiveWordDto swdto = new SensitiveWordDto();
            swdto.setId(sw.getId());
            swdto.setWord(sw.getWord());
            swdto.setStatus(sw.getStatus().getCode());
            swdto.setCreateTime(sw.getCreateTime());
            return swdto;
        }).collect(Collectors.toList());
        return words;
    }

    @GetMapping("/allow")
    public List<SensitiveWordDto> getAllow() {
        List<SensitiveWordDto> words = sensitiveWordService.listAllow().stream().map(sw -> {
            SensitiveWordDto swdto = new SensitiveWordDto();
            swdto.setId(sw.getId());
            swdto.setWord(sw.getWord());
            swdto.setStatus(sw.getStatus().getCode());
            swdto.setCreateTime(sw.getCreateTime());
            return swdto;
        }).collect(Collectors.toList());
        return words;
    }

    @GetMapping("/findInText")
    public List<String> findInText(@RequestBody SensitiveWordFindReqBody body) {
        return sensitiveWordBsService.findInText(body.getText());
    }

    @PostMapping("")
    public ResponseEntity<?> save(@RequestBody SensitiveWordDto swdto) {
        LambdaQueryWrapper<SensitiveWord> lambdaQueryWrapper = new LambdaQueryWrapper<SensitiveWord>();
        lambdaQueryWrapper.eq(SensitiveWord::getWord, swdto.getWord());
        SensitiveWord sensitiveWord = sensitiveWordService.getOne(lambdaQueryWrapper);
        if (sensitiveWord != null) {
            return ResponseEntity.status(HttpStatus.CONFLICT).body("Already exist!");
        }

        StatusEnum se = StatusEnum.getEnumByCode(swdto.getStatus());

        SensitiveWord newSensitiveWord = new SensitiveWord(null, swdto.getWord(), se, null, 0);
        if (sensitiveWordService.save(newSensitiveWord)) {
            sensitiveWordBsService.add(newSensitiveWord);
            SensitiveWordDto body = SensitiveWordDto.builder()
                    .id(newSensitiveWord.getId())
                    .word(newSensitiveWord.getWord())
                    .status(newSensitiveWord.getStatus().getCode())
                    .createTime(newSensitiveWord.getCreateTime())
                    .build();

            return ResponseEntity.status(HttpStatus.CREATED).body(body);
        }

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Save failed!");
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<?> delete(@PathVariable Integer id) {
        SensitiveWord sensitiveWord = sensitiveWordService.getById(id);
        if (sensitiveWord == null) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Not exist!");
        }

        if (sensitiveWordService.removeById(id)) {
            sensitiveWordBsService.remove(sensitiveWord);
            return ResponseEntity.status(HttpStatus.OK).body("Remove success!");
        }

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Remove failed!");
    }

    @PutMapping("")
    public ResponseEntity<?> update(@RequestBody SensitiveWordDto swdto) {
        SensitiveWord sensitiveWord = sensitiveWordService.getById(swdto.getId());
        if (sensitiveWord == null) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Not exist!");
        }

        SensitiveWord updatedSensitiveWord = new SensitiveWord();
        updatedSensitiveWord.setId(swdto.getId());
        updatedSensitiveWord.setWord(swdto.getWord());
        updatedSensitiveWord.setStatus(StatusEnum.getEnumByCode(swdto.getStatus()));

        if (sensitiveWord.getWord().equals(swdto.getWord())
                && sensitiveWord.getStatus().getCode() == swdto.getStatus()) {
            return ResponseEntity.status(HttpStatus.NOT_MODIFIED).body("No change!");
        }

        if (sensitiveWordService.updateById(updatedSensitiveWord)) {
            sensitiveWordBsService.remove(sensitiveWord);
            sensitiveWordBsService.add(updatedSensitiveWord);
            SensitiveWordDto body = SensitiveWordDto.builder().id(updatedSensitiveWord.getId())
                    .word(updatedSensitiveWord.getWord())
                    .status(updatedSensitiveWord.getStatus().getCode())
                    .createTime(sensitiveWord.getCreateTime())
                    .build();
            return ResponseEntity.status(HttpStatus.OK).body(body);
        }

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Update failed!");
    }
}
